package sunyu.tools.common;

import org.nutz.http.*;
import org.nutz.lang.util.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Http工具类
 *
 * @author 孙宇
 */
@Component
public class HttpTools {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @PostConstruct
    public void init() {
        Sender.setup(Executors.newFixedThreadPool(4));
    }

    @PreDestroy
    public void destroy() {
        Sender.shutdown();
    }

    /**
     * 访问一个URL
     *
     * @param url 需要访问的URL
     * @return http响应
     */
    public Response get(String url) {
        return Http.get(url);
    }

    /**
     * 异步调用get
     *
     * @param url
     * @param callback
     * @return
     */
    public Future<Response> get(String url,
                                Callback<Response> callback) {
        return Sender.create(url).send(callback);
    }

    /**
     * 访问一个URL,并设置超时
     *
     * @param url     需要访问的URL
     * @param timeout 超时设置,单位为毫秒
     * @return http响应
     */
    public Response get(String url,
                        int timeout) {
        return Http.get(url, timeout);
    }

    /**
     * 异步调用get
     *
     * @param url
     * @param timeout
     * @param callback
     * @return
     */
    public Future<Response> get(String url,
                                int timeout,
                                Callback<Response> callback) {
        return Sender.create(url, timeout).send(callback);
    }

    /**
     * 访问一个URL,并设置超时及参数
     *
     * @param url    需要访问的URL
     * @param params 参数
     * @return http响应
     */
    public Response post(String url,
                         Map<String, Object> params) {
        return Http.post2(url, params, Integer.MAX_VALUE);
    }

    /**
     * 异步
     *
     * @param url
     * @param params
     * @param callback
     * @return
     */
    public Future<Response> post(String url,
                                 Map<String, Object> params,
                                 Callback<Response> callback) {
        return Sender.create(Request.create(url, Request.METHOD.POST, params, null)).setTimeout(Integer.MAX_VALUE).send(callback);
    }


    /**
     * 访问一个URL,并设置超时及参数
     *
     * @param url     需要访问的URL
     * @param params  参数
     * @param timeout 超时设置,单位为毫秒
     * @return http响应
     */
    public Response post(String url,
                         Map<String, Object> params,
                         int timeout) {
        return Http.post2(url, params, timeout);
    }

    public Future<Response> post(String url,
                                 Map<String, Object> params,
                                 int timeout,
                                 Callback<Response> callback) {
        return Sender.create(Request.create(url, Request.METHOD.POST, params, null)).setTimeout(timeout).send(callback);
    }

    /**
     * 访问一个URL,并设置超时及参数
     *
     * @param url    需要访问的URL
     * @param body   消息体
     * @param header 消息头
     * @return http响应
     */
    public Response post(String url,
                         Object body,
                         Header header) {
        return Http.post3(url, body, header, Integer.MAX_VALUE);
    }

    public Future<Response> post(String url,
                                 Object body,
                                 Header header,
                                 Callback<Response> callback) {
        return post(url, body, header, Integer.MAX_VALUE, callback);
    }

    /**
     * 访问一个URL,并设置超时及参数
     *
     * @param url     需要访问的URL
     * @param body    消息体
     * @param header  消息头
     * @param timeout 超时时间
     * @return http响应
     */
    public Response post(String url,
                         Object body,
                         Header header,
                         Integer timeout) {
        return Http.post3(url, body, header, timeout);
    }

    public Future<Response> post(String url,
                                 Object body,
                                 Header header,
                                 Integer timeout,
                                 Callback<Response> callback) {
        Request req = Request.create(url, Request.METHOD.POST).setHeader(header);
        if (body != null) {
            if (body instanceof InputStream) {
                req.setInputStream((InputStream) body);
            } else if (body instanceof byte[]) {
                req.setData((byte[]) body);
            } else {
                req.setData(String.valueOf(body));
            }
        }
        return Sender.create(req).setTimeout(timeout).send(callback);
    }

}
